package com.qfx.demo.service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import com.qfx.demo.cache.UserCache;
import com.qfx.demo.util.ToolToken;
import com.qfx.demo.vo.MessageBean;
import com.qfx.demo.vo.SysUser;

@Service
public class LoginService {
	
	private final Logger logger = LogManager.getLogger(getClass());

	/**
	 * @功能描述：	保存用户注册信息
	 *
	 * @作者：zhangpj		@创建时间：2017年6月2日
	 * @param request
	 * @param sysUser
	 * @return
	 */
	public boolean saveUser(HttpServletRequest request,SysUser sysUser){
		MessageBean messageBean = new MessageBean();
		
		try {
			// 1.生成加密盐值和加密后的密码
			setUserInfo(sysUser);
			// 2.保存用户信息到缓存中
			UserCache.setUserCacheMap(sysUser.getUserName(), sysUser);
			logger.info("用户["+sysUser.getUserName()+"]注册成功");
			messageBean.setMessage("注册成功,请登录!");
			messageBean.setResult(true);
		} catch (Exception e) {
			logger.error("用户["+sysUser.getUserName()+"]注册失败");
			messageBean.setMessage("注册失败,请重新注册");
			messageBean.setObj(sysUser);
		}
		request.setAttribute("messageBean", messageBean);

		return messageBean.getResult();
	}
	
	/**
	 * @功能描述：shiro+jwt登录验证,通过返回true,失败返回false
	 *
	 * @作者：zhangpj		@创建时间：2017年6月2日
	 * @param request
	 * @param sysUser
	 * @return
	 */
	public MessageBean loginJwt(SysUser sysUser, HttpServletResponse response){
		String message = "";
		MessageBean messageBean = new MessageBean();
		
		System.out.println("用户登录:userName["+sysUser.getUserName()+"],userPass["+sysUser.getPassWord()+"]");
		
		// 获取用户信息
        SysUser user = UserCache.getUserCacheMap(sysUser.getUserName());
        if (ObjectUtils.isEmpty(user)) {
        	message = "用户不存在!";
        	messageBean.setMessage(message);
        	System.out.println("用户[" + sysUser.getUserName() + "]进行登录验证失败,失败原因["+message+"]");
        	
        	return messageBean;
		}
        
        sysUser.setSalt(user.getSalt());
        // 生成加密盐值(如果已经传入加密盐值则使用指定的加密盐值)和加密后的密码
        setUserInfo(sysUser);
        
        if (!sysUser.getPassWord().equals(user.getPassWord())) {
        	message = "密码错误!";
        	messageBean.setMessage(message);
        	System.out.println("用户[" + sysUser.getUserName() + "]进行登录验证失败,失败原因["+message+"]");
        	
        	return messageBean;
		}
		
        // 获取系统时间戳
        long currentTimeMillis = System.currentTimeMillis();
        
        // 生成Token:userName + 时间戳 + salt
		String tokenStr = ToolToken.createJwtToken(sysUser.getUserName() + currentTimeMillis + sysUser.getSalt(), sysUser.getUserName());
		if (ObjectUtils.isEmpty(tokenStr)) {
			message = "生成token发生错误!";
			messageBean.setMessage(message);
			System.out.println("用户[" + sysUser.getUserName() + "]进行登录验证失败,失败原因["+message+"]");
			return messageBean;
		}
		
		System.out.println("用户[" + sysUser.getUserName() + "]登录认证通过");
		messageBean.setObj(tokenStr);
		messageBean.setResult(true);
		
		// 将 Token 放入 Response Header 中
        response.addHeader("Authorization", tokenStr);
		
		return messageBean;
	}
	
	// -------------------- private method --------------------
	/**
	 * @功能描述：生成加密盐值(如果已经传入加密盐值则使用指定的加密盐值)和加密后的密码,
	 *
	 * @作者：zhangpj		@创建时间：2017年5月18日
	 * @param sysUser
	 */
	private void setUserInfo(SysUser sysUser){
		String algorithmName = "md5";	//设置加密方式,需要与shiro配置文件中加密方式匹配
		String userName = sysUser.getUserName();	// 注册名
		String passWord = sysUser.getPassWord(); // 注册密码
		String salt = sysUser.getSalt(); // 加密盐值
		if (ObjectUtils.isEmpty(salt)) {
			// 生成加密盐值:随机数
			salt = new SecureRandomNumberGenerator().nextBytes().toHex();
		}
		int hashIterations = 3; //设置加密迭代次数,需要与shiro配置文件中加密迭代次数匹配
		
		// 生成密码时使用"用户名+盐值"来生成加密数据
		SimpleHash hash = new SimpleHash(algorithmName, passWord,userName + salt, hashIterations);
		String encodedPassword = hash.toHex();
		
		sysUser.setUserName(userName);
		sysUser.setSalt(salt);
		sysUser.setPassWord(encodedPassword);
	}
	
	public void sayHello(){
		System.out.println("ldkdkdkkkkkkkkkkkkkkkkkkkkk");
	}
	
	
	public static void main(String[] args) {
		String algorithmName = "md5";	//设置加密方式,需要与shiro配置文件中加密方式匹配
		String userName = "linlin";	// 注册名
		String passWord = "111111"; // 注册密码
		// 生成加密盐值:随机数
//		String salt = "f651bc1d5c94dd65700bd580aee66d24";
		String salt = new SecureRandomNumberGenerator().nextBytes().toHex();
		int hashIterations = 3; //设置加密迭代次数,需要与shiro配置文件中加密迭代次数匹配
		
		// 生成密码时使用"用户名+盐值"来生成加密数据
		SimpleHash hash = new SimpleHash(algorithmName, passWord, userName + salt, hashIterations);
		String encodedPassword = hash.toHex();
		
//		for (int i = 0; i < 10; i++) {
			System.out.println(salt);
			System.out.println(encodedPassword);
//		}
	}
}
